﻿using System;

namespace Safebrowsing
{
    /// <summary>
    /// This policy is used if client is in the backoff mode.
    /// The client enters backoff mode if receives several errors within small interval of time.
    /// </summary>
    public class BackoffPolicy
    {
        /// <summary>
        /// Creates an instance of the BackoffPolicy and initailzes all properties to the default values
        /// </summary>
        public BackoffPolicy()
        {
            ErrorsCountToEnterBackoffMode = 2;
            ErrorsTimeout = 60*5;
            BackoffTimeout = new TimeSpan(8, 0, 0);
            ErrorIntervals = new TimeSpan[3];
            ErrorIntervals[0] = new TimeSpan(0, 30, 0); // 30 minutes
            ErrorIntervals[1] = new TimeSpan(1, 0, 0); // 1 hour
            ErrorIntervals[1] = new TimeSpan(2, 0, 0); // 2 hours
        }

        /// <summary>
        /// Errors count to enter backoff mode
        /// </summary>
        public int ErrorsCountToEnterBackoffMode { get; set; }

        /// <summary>
        /// If a client receives ErrorsCountToEnterBackoffMode count of errors during ErrorsTimeout seconds, it enters backoff mode.
        /// </summary>
        public int ErrorsTimeout { get; set; }

        /// <summary>
        /// If last error occured at least BackoffTimeout time ago, client exits backoff mode.
        /// Default value is 8 hours.
        /// </summary>
        public TimeSpan BackoffTimeout { get; set; }

        /// <summary>
        /// Array containing intervals client must wait after error occur.
        /// Array index + 1 -- error number.
        /// Value is delay in seconds.
        /// 
        /// While in backoff mode, the client MUST not ping for at least a certain amount of time from the last error. 
        /// 
        /// Default values are:
        /// ErrorIntervals[0] = new TimeSpan(0,30,0); // 30 minutes
        /// ErrorIntervals[1] = new TimeSpan(1,0,0); // 1 hour
        /// ErrorIntervals[1] = new TimeSpan(2,0,0); // 2 hours
        /// 
        /// That is:
        /// When the client receives the first error, it MUST not ping for at least 30 minutes from the last error.
        /// If it receives another error, the client MUST not ping for at least 1 hour.
        /// If it receives another error, the client MUST not ping for at least 2 hours.
        /// After that, the client MUST wait at least 2 hours between pings.
        /// </summary>
        public TimeSpan[] ErrorIntervals { get; set; }
    }
}